/*功能：工具js，包含了
 * 日志、
 * 提示框：alert（提示框）、确认框（confirm）、弹出框（dialog）
 * 简化的提示框warn（警告）、success（成功）、error（错误）、info（提示）等
 * 创建人：吕凯 2020-11-5*/
$ = jQuery;
var tjSubmitClickEle; //提交按钮,待调整
if("undefined" == typeof ctxPath ){
	ctxPath = ''; //项目路径，需要在init前覆盖
}
var Touchjs = {
	/** 主题内容
    @type jQueryObject
    */
	contentMainE:$("body"),
    dialogE : null,
	// 覆盖消息提醒方法
	log : function(msg) {
		if (typeof(console) != "undefined"){
			console.log(new Date());
			console.log(msg);
		}
    }
    ,_msg:{}
    /**    根据key及传入参数获取模板信息，如设置模板 _msg["welcome"]="欢迎{0}来到{1}"; 调用模板 msg("welcome", ["张三","海底大世界"])
        @param key  {String}        内置消息模板的key
        @param args {Array(Object)} 替换模板变量的参数
        @returns {String}           替换参数后的模板信息  */
    ,msg : function(key, args){
        return format(this._msg[key], args);
    }
    /**    根据字符串及传入参数返回文字，如 format("欢迎{0}来到{1}", ["张三","海底大世界"])
    @param str  {String}        待处理的文字
    @param args {Array(Object)} 替换变量的参数
    @returns {String}           替换参数后的信息  */
    ,format : function(str, args) {
        args = args || [];
        var result = str || "";
        for (var i = 0; i < args.length; i++){
            result = result.replace(new RegExp("\\{" + i + "\\}", "g"), args[i]);
        }
        return result;
    }
    /**    根据js模板字符串及传入数据返回结果，默认使用了doT，可以使用其他的替换
    @param str  {String}        js模板字符串
    @param data {Json}          数据，json对象
    @param ele {jQueryObject}   调用对象
    @returns {String}           处理后的内容  */
    ,template : function(str, data, ele) {
        var result = str || "";
        result = doT.template(str)(data); //处理js模板
        return result;
    }
    /**    内部变量设置（可设置是否调试模式）
     @enum {Boolean}
     @readonly    */
    ,_set:{
        /** 调试模式，部署时关闭 */
        debug:true 
    }
    /**    调试输出是否输出堆栈信息
        @param msg {Boolean} 是否输出堆栈信息
     */
    ,debugTrace : false
    /**    调试输出
        @param msg   {String}  调试信息
        @param trace {Boolean} 输出堆栈信息
    */
    ,debug : function(msg, trace){
        if (this._set.debug) {
            if (typeof(console) != "undefined"){
                var logInfo = new Date()+" "+msg;
                if (trace || Touchjs.debugTrace) {
                    logInfo += " by:" + printCallStack();
                }
                console.log(logInfo);
            } 
        }
    },
	loadingHtml:"加载中……",
	/**    轻量级的提示框
	 * @param title   {String}   标题
	 * @param message {String}   内容
	 * @param type    {String}   提示类型，支持warning（警告）、success（成功）、error（错误）、info（提示）等
	 * @param yesFn   {Function} 点击确定后的执行函数
	 */
	tinyAlert : function(message, type, yesFn) {
		if (!jQuery.message) {
			this.log("缺少依赖JS库：jQuery.message！");
			return;
		}
		if ("success" != type && "error" != type && "info" != type && "warning" != type) {
    		type = "info";
    	}
		/*var extendsCls = 'layui-layer-hui';
		var optionsDefault = {
			offset: 't', 
			anim : 5,  //  0 	平滑放大。默认  1 	从上掉落  2:从最底部往上滑入 3:从左滑入 4:从左翻滚  5:渐显  6:抖动
		  	time: 60000, //2秒关闭（如果不配置，默认是3秒）
		  	icon:1,
		  	skin: 'shieldjs-custom-layer '+extendsCls //自定义样式,默认layui-layer-hui
		};*/
		//layer.msg(result.message, optionsDefault);
		/*message:' 操作成功',    //提示信息
		time:'2000',           //显示时间（默认：2s）
		type:'success',        //显示类型，包括4种：success,error,info,warning
		showClose:false,       //显示关闭按钮（默认：否）
		autoClose:true,        //是否自动关闭（默认：是）*/			
		$.message({
	        message: message,
	        type:type
	    });
	    if (yesFn && $.isFunction(yesFn)) {
			yesFn();
		}
	},
	/**    检查是否使用tinyAlert轻量级提示框
	 * @param title   {String}   标题
	 * @param message {String}   内容
	 * @param type    {String}   提示类型，支持warning（警告）、success（成功）、error（错误）、info（提示）等
	 * @returns {Object}         处理后的结果，包括2个字段tiney和message，如{tiny:false,message:message}
	 */
	checkTinyAlert : function(title, message, type) {
		var result = {tiny:false,message:message}
		if(message.indexOf("tiny:")>-1){
			result.tiny = true;
			result.message = message.substring(5);
		}
		return result;
	},
	/**    提示框
	 * @param title   {String}   标题
	 * @param message {String}   内容
	 * @param type    {String}   提示类型，支持warning（警告）、success（成功）、error（错误）、info（提示）等
	 * @param yesFn   {Function} 点击确定后的执行函数
	 */
	alert : function(title, message, type, yesFn) {
		var ops = {title:title, skin: 'layui-layer-chouui', zIndex:20000000 };
		var tiny = false; //轻量级的，一般不刷新页面
		
		var checkTinyAlertResult = this.checkTinyAlert(title, message, type);
		tiny = checkTinyAlertResult.tiny;
		message = checkTinyAlertResult.message;
		
		if (tiny) {
			this.tinyAlert(message, type, yesFn);
        } else {
        	if(typeof layer == "undefined" ){
        		this.log("缺少依赖JS库：layer！");
        		return;
        	}
        	if ("success" == type) {
        		ops.icon = 1;
        	} else if ("error" == type) {
        		ops.icon = 2;
        	} else if ("info" == type) {
        		ops.icon = 0;
        	} else if ("warning" == type) {
        		ops.icon = 0;
        	} else {
        		layer.msg(message);
        		return;
        	}
        	layer.alert(message, ops, function(index){
        		//do something
        		if (yesFn && $.isFunction(yesFn)) {
        			yesFn(index);
        		}
        		layer.close(index);
        	});
        }
	}
    /**    确认框
	 * @param title    {String}   标题
	 * @param message  {String}   内容
	 * @param okFn     {Function} 点击确定后的执行函数
	 * @param cancelFn {Function} 点击取消后的执行函数
	 */
	,confirm : function(title, message, okFn, cancelFn){
		if(typeof layer == "undefined" ){
			this.log("缺少依赖JS库：layer！");
			return;
		}
		layer.confirm(message, {
			title:title
			,skin: 'layui-layer-chouui'
		}, function(index){
			if (okFn && $.isFunction(okFn)) {
				okFn(index);
			}
			layer.close(index); //关闭
		}, function(index){
			if (cancelFn && $.isFunction(cancelFn)) {
				cancelFn();
			}
		});
	}
	,warn : function(title, message, okFn) {
		var msg = "警告";
		if (message && $.isFunction(message)) { // 2个参数，递推
			okFn = message;
			message = title;
			title = msg;
        }
		if (!message) { // 只有一个参数，那么这个参数就是message，增加默认标题
			message = title;
			title = msg;
        }
		this.alert(title, message, "warning", okFn);
	}
	,success : function(title, message, okFn) {
		var msg = "成功";
		if (message && $.isFunction(message)) { //
			okFn = message;
			message = title;
			title = msg;
        }
		if (!message) {
			message = title;
			title = msg;
        }
		this.alert(title, message, "success", okFn);
	}
	/**    错误提示框
	 * @param title   {String} 标题
	 * @param message {String} 内容
	 * @param okFn    {Function} 点击确定后的执行函数
	 * @param error   {Error} 异常信息
	 */
	,error : function(title, message, okFn, error) {
		var msg = "错误";
		if (okFn && $.type(okFn) == "error") { // 检验参数，第3个参数如果为异常，则第3个参数为error，ok为null
			error = okFn;
			okFn = null;
        }
		if (message && $.isFunction(message)) { // 检验参数，第2个参数如果为函数，则第2个参数为ok，第1个为message，title使用默认
			okFn = message;
			message = title;
			title = msg;
        }
		if (message && $.type(message) == "error") { // 检验参数，第2个参数如果为错误，则第2个参数为error，第1个为message，title使用默认
			error = message;
			okFn = null;
			message = title;
			title = msg;
        }
		if (!message) { //  补齐参数，只定义了一个参数，则该参数为内容，title使用默认
			message = title;
			title = msg;
        }
		if (error) {
			printCallStack(error);
        }
		this.alert(title, message, "error", okFn);
	}
	,info : function(title, message, okFn) {
		var msg = "提示";
		if (message && $.isFunction(message)) { //
			okFn = message;
			message = title;
			title = msg;
        }
		if (!message) {
			message = title;
			title = msg;
        }
		this.alert(title, message, "info", okFn);
	}
	,tips : function(ele, content, options) {
		var $this = ele;
		if(content){
			var width = $this.data("width");
			var extendsCls = $this.data("tipsClass")||'';
			var optionsDefault = {
				tips: 1, // tips[1,'#3595CC']1 上方 2右方 3下方4左, '#3595CC'
				area: width ? (width+'px'):'auto', //宽度，高度自适应
			  	time: -1, //自动隐藏的时间，-1表示不自动隐藏
			  	skin: 'shieldjs-custom-layer '+extendsCls, //自定义样式
			  	title: '提示信息',
			  	cancel: function(index, layero){ 
			  	  if(confirm('确定要关闭么')){ //只有当点击confirm框的确定时，该层才会关闭
			  	    layer.close(index)
			  	  }
			  	  return false; 
			  	}    
			};
			options = $.extend(true, {}, optionsDefault, options);
			delete options["url"];//删除属性
			delete options["content"];//删除属性
			//console.log(options)
			
			var triggerMethod = ele.data("trigger"); //支持hover和click方法
			var showMethodFns = ele.data("show")||"mouseenter"; //如click mouseenter
			var hideMethodFns = ele.data("hide")||"mouseleave"; //如unfocus
			if (!triggerMethod) { //未定义trigger
				function hideTips($this){
					var index = $this.data("touchjs_tips_fn");
					if(!index){
						index = $this.closest('html').data("touchjs_tips_fn");
					}
					layer.close(index);
					$this.removeData("touchjs_tips_fn"); //移除
					$this.closest('html').removeData("touchjs_tips_fn"); //移除
				}
				
				var showMethods = showMethodFns.split(" ");
				var hideMethods = hideMethodFns.split(" ");
				$.each(showMethods, function(i, showMethod) {
	                
					$this.off(showMethod+".touchjs_tips").on(showMethod+".touchjs_tips",function(){
						var touchjs_tips_fn = layer.tips(content, $this, options);
						$this.data("touchjs_tips_fn", touchjs_tips_fn); //添加
						$this.closest('html').data("touchjs_tips_fn", touchjs_tips_fn); //添加
					});
                });
				$.each(hideMethods, function(i, hideMethod) {
	                
					if(('' + hideMethod).indexOf('unfocus') > -1) { //不能获取焦点，变动到html的鼠标点击上
						$this.off("mousedown.touchjs_tips touchstart.touchjs_tips").on("mousedown.touchjs_tips touchstart.touchjs_tips", function(){ //点击到自己身上时不冒泡
							return false;
						});
						$this.closest('html').off("mousedown.touchjs_tips touchstart.touchjs_tips").on("mousedown.touchjs_tips touchstart.touchjs_tips", function() {
							console.log(1)
							hideTips($this);
						});
					} else {
						
						$this.off(hideMethod+".touchjs_tips").on(hideMethod+".touchjs_tips",function(){
							hideTips($this);
						});
					}
                });
				
			} else {
				$this.off(triggerMethod+".touchjs_tips").on(triggerMethod+".touchjs_tips", function(){
					var touchjs_tips_fn =  $this.data("touchjs_tips_fn");
					if (touchjs_tips_fn) {
						layer.close(touchjs_tips_fn); //关闭旧弹窗
						$this.removeData("touchjs_tips_fn"); //移除
                    }
					touchjs_tips_fn = layer.tips(content, $(this), options);
					$this.data("touchjs_tips_fn", touchjs_tips_fn); //添加
				});
			}
			
		}
    }
	//搜索时自动补全
	,keyCode : {
	    ENTER: 13, ESC: 27, END: 35, HOME: 36,
	    SHIFT: 16, TAB: 9, BLANK: 32, CAPSLOCK:20,
	    LEFT: 37, RIGHT: 39, UP: 38, DOWN: 40,
	    DELETE: 46, BACKSPACE:8
	},
	options : {
		/** load方法失败回调方法(actionName, e) */
		loadErrorCallback : null
		/** load方法成功回调方法 */
		,loadSuccCallback : null
		/** load方法完成回调方法（成功失败都会调用）*/
		,loadCallback : null
	},
	// 检查自定义回调方法是否存在
	hasEventFn : function(ele, eventName) {
		var $events = $._data(ele[0], "events");
		if( $events && $events[eventName] ){
			return true;
		}
		return false;
	},
	// 自定义加载完成后的回调
	loadCallback : function(ele, namespace) {
		var eventName = "loadCallback";
		if (Touchjs.hasEventFn(ele, eventName)) { //其实可以直接绑定，此处增加判断是否存在
			var $events = $._data(ele[0],"events");
			if( $events && $events[eventName] ){
				ele.triggerHandler(eventName);
			}
        }
		ele.triggerHandler("touch.touchjs"); // 触发自定义事件
		if (namespace) {
			ele.triggerHandler("touch.touchjs."+namespace); // 触发自定义事件
        }
	},
	
	
	/**	表单提交成功后的回调方法
	 * @param successDo    {String} 成功后的回调方法名
	 * @param formE        {jQuery} 表单对象/调用对象
	 * @param targetE      {jQuery} 表单提交的目标对象,容器对象
	 * @param data         {Object} 返回结果的对象可能为json也可能为页面字符
	 * @param clickEle     {jQuery} 点击对象，如左侧栏menu或者a链接 
	 * @param searchForm   {jQuery} 搜索表单  
	 * @param dialog       {Touchjs.dialog} 弹出框对象
	 *  */
	formSubmitCallback : function(successDo, formE, targetE, data, clickEle, searchForm, dialog ) {
		var successDoForm = successDo||Touchjs.successDo.refresh;
		if (hasAttr(formE, "successDo")) { //form上保存成功后的处理
			successDoForm = formE.attr("successDo");
		}
		// 查找是否存在点击元素和搜索表单
		var clickEle = formE.data("successdo-click")||clickEle;
		if (clickEle) {
			clickEle = getjQueryObj(clickEle);
        }
		var searchForm = formE.data("successdo-searchform")||searchForm;
		if (searchForm) {
			searchForm = getjQueryObj(searchForm);
        }
		if (successDoForm) { //回调
			if (!Touchjs.checkSuccessDoMethodExist(successDoForm)) {
				return false;
			} else {
				// 为json格式
				var json;
				if (typeof data == 'object') {
					json = data;
				} else {
					try {
						json = $.parseJSON(data);
					} catch (e) {
						json = '';
					}
				}
				Touchjs.execSuccessDoMethod(successDoForm, targetE, formE, searchForm, clickEle, dialog, json.refresh, json);
			}
		}
		if (targetE && targetE.is(":visible")) { //未关闭
			Touchjs.touch(targetE); //继续加载
        }  
    },
	/**	处理成功后的回调方法名
	 * @class Touchjs.successDo */
	successDo : {
		/**	刷新，关闭dialog，并刷新搜索表单(默认)
		 * @type String */
		refresh: "refresh",
		/**	什么都不做
		 * @type String */
		donothing: "donothing",
		/**	跳转链接
		 * @type String */
		href: "href",
		/**	只刷新搜索表单
		 * @type String */
		research: "research",
		/**	只关闭dialog
		 * @type String */
		dialogRemove: "dialogRemove",
		/**	刷新Tab（有dialog也会关闭）,用于多页签内容页的刷新
		 * @type String */
		refreshTab: "refreshTab",
		/**	刷新Tab（不关闭dialog）,用于多页签内容页的刷新
		 * @type String */
		refreshTabIgnoreDialog: "refreshTabIgnoreDialog",
		/**	自定义方法
		 * @type String */
		shieldExtend: "shieldExtend" //
	},
	/**	处理成功后的回调执行方法
	 * @class Touchjs.successDoMethod */
	successDoMethod : {
		/**	表单提交成功后的回调方法：刷新
		 * @param containerE   {jQuery} 容器对象
		 * @param invokeEle    {jQuery} 调用对象
		 * @param targetE      {jQuery} 表单提交的目标对象
		 * @param data         {Object} 返回结果的对象可能为json也可能为页面字符
		 * @param clickEle     {jQuery} 点击对象，如左侧栏menu或者a链接 
		 * @param searchForm   {jQuery} 搜索表单  
		 * @param dialog       {Touchjs.dialog} 弹出框对象
		 *  */
		refresh : function(containerE, invokeEle, searchForm, clickEle, dialog, jsonRefresh, result){ //刷新，关闭dialog，并刷新搜索表单(默认)
			if (dialog) {
				dialog.close();
			}
			if (!clickEle) { // 未定义时	
				var clickv = invokeEle.data("successdo-click");
				if (clickv) {
					clickEle = getjQueryObj(clickv);
		        }		
				if (!clickEle || clickEle.length == 0) { 
					clickEle = invokeEle.closest("[data-pjax-target]").find(".touchjs-page a.active"); //先找调用者上级是否存在，pjax的翻页
				}
				
				if (!clickEle || clickEle.length == 0) { 
					if (containerE) { 
						clickEle = containerE.find("[data-pjax-target]").find(".touchjs-page a.active"); //没有则找容器范围内的pjax的翻页
                    }
					if (clickEle.length == 0) { // 整个页面范围内查找
						clickEle = $("[data-pjax-target]").find(".touchjs-page a.active"); //pjax的翻页
					}
					
				}
            }
            if (!searchForm) { // 未定义时
            	searchForm = invokeEle.closest(".touchjs-submitform"); //自动提交表单
            }
            
            if(result.forward_url){
            	window.location.href = result.forward_url; //跳转到指定页面
            } else if (clickEle && clickEle.length >0) { // 左侧菜单点击或者a链接等
				clickEle.click();
			} else if (searchForm && searchForm.length >0) { //搜索表单提交
				if (!jsonRefresh) { //兼容旧框架的json返回，不重复刷新
					searchForm.submit();
				}
			} else if (invokeEle.data("successdo-url")) { //回调url
				window.location.href = invokeEle.data("successdo-url"); //跳转到指定页面
			} else{
				window.location.reload(); //刷新当前页面
			}
		},
		donothing : function(containerE, invokeEle, searchForm, clickEle, dialog, jsonRefresh, result) { //什么都不做
		},
		href : function(containerE, invokeEle, searchForm, clickEle, dialog, href, result) { //跳转到指定href
			window.location.href = result.forward_url || href || invokeEle.data("successdo-url"); //跳转到页面
		},
		research : function(containerE, invokeEle, searchForm, clickEle, dialog, jsonRefresh, result) { //只刷新搜索结果
			if (clickEle && clickEle.length >0) { // 左侧菜单点击或者a链接等
				clickEle.click();
			} else if (searchForm && searchForm.length >0) { //搜索表单提交
				if (!jsonRefresh) { //兼容旧框架的json返回，不重复刷新
					searchForm.submit();
				}
			}
		},
		dialogRemove : function(containerE, invokeEle, searchForm, clickEle, dialog, jsonRefresh, result) { //只关闭dialog
			if (dialog) {
				dialog.close();
			}
		},
		refreshTabDealFn : function(containerE, invokeEle, searchForm, clickEle, dialog, closeDialog) { //刷新Tab处理函数，内部使用
			var multiTabEle = containerE.find(".touchjs-multiTab");
			if (multiTabEle.length > 0) {
				if (closeDialog && dialog) {
					dialog.close();
				}
				// 选择当前tab页签，并刷新
				var multiTitleActiveE = containerE.find("."+$.fn.multiTab.defaults.cssTitle+"."+$.fn.multiTab.defaults.cssTitleActive);
				multiTitleActiveE.triggerHandler("refresh");
			}
		},
		refreshTab : function(containerE, invokeEle, searchForm, clickEle, dialog, jsonRefresh, result) { //刷新Tab,用于多页签内容页的刷新
			Touchjs.successDoMethod.refreshTabDealFn(containerE, invokeEle, searchForm, clickEle, dialog, true)
		},
		refreshTabIgnoreDialog : function(containerE, invokeEle, searchForm, clickEle, dialog, jsonRefresh) { //刷新Tab（不关闭，dialog）,用于多页签内容页的刷新
			Touchjs.successDoMethod.refreshTabDealFn(containerE, invokeEle, searchForm, clickEle, dialog, false)
		},
		shieldExtend : function(containerE, invokeEle, searchForm, clickEle, dialog, jsonRefresh, result) { //自定义

		}
	},
	/**	检查成功的回调函数是否存在
	 * @param successDoName {String} 成功后的回调方法名
	 * @returns  {Boolean} 方法存在时返回true，否则返回false */
	checkSuccessDoMethodExist : function (successDoName) {
		if(!$.isFunction(Touchjs.successDoMethod[successDoName])){
			var successDoExtendFn = eval(successDoName); //自定义的回调方法
			if(!$.isFunction(successDoExtendFn)){
				Touchjs.error(successDoName + "成功后的回调处理函数不存在！");
				return false;
			}
		}
		return true;
	},
	/**	指定成功的回调函数,result为成功返回的结果
	 * @param successDoName {String} 成功后的回调方法名 */
	execSuccessDoMethod : function (successDoName, containerE, invokeEle, searchForm, clickEle, dialog, oldRefresh, result) {
		if($.isFunction(Touchjs.successDoMethod[successDoName])){ //预定义的回调方法
			Touchjs.successDoMethod[successDoName](containerE, invokeEle, searchForm, clickEle, dialog, oldRefresh, result);
		} else {
			var successDoExtendFn = eval(successDoName); //自定义的回调方法
			if($.isFunction(successDoExtendFn)){
				successDoExtendFn(containerE, invokeEle, searchForm, clickEle, dialog, oldRefresh, result);
			}
		}
	},
	//post提交数据
	postData : function(url, params, containerE, invokeEle, searchForm, clickEle, shieldDialog, successDo, methodType, successCallback) {
		var method = "post";
		if ($.isFunction(methodType)) { //是函数，则为successCallback
			successCallback = methodType;
		}else {
			method = methodType;
		}
		if (!successDo && hasAttr(invokeEle, "successDo")) { //form上保存成功后的处理
			successDo = invokeEle.attr("successDo");
        }
		// 查找是否存在点击元素和搜索表单
		if (!clickEle) {
			clickEle = invokeEle.data("successdo-click")||clickEle;
			if (clickEle) {
				clickEle = getjQueryObj(clickEle);
			}
        }
		if (!searchForm) {
			searchForm = invokeEle.data("successdo-searchform")||searchForm;
			if (searchForm) {
				searchForm = getjQueryObj(searchForm);
			}
        }
		if (method == "get") {
			Touchjs.ajax.get(null, url, params, function(json) {
				Touchjs.execSuccessDoMethod(successDo, containerE, invokeEle, searchForm, clickEle, shieldDialog, json.refresh, json);
        		if (successCallback) {
        			successCallback();
                }
        	}, function(json) {
        		Touchjs.debug("提交数据出错！" + url + " params: " + $.param(params));
        	});
        } else {
        	Touchjs.ajax.post(url, params, function(json) {
        		Touchjs.execSuccessDoMethod(successDo, containerE, invokeEle, searchForm, clickEle, shieldDialog, json.refresh, json);
        		if (successCallback) {
        			successCallback();
                }
        	}, function(json) {
        		Touchjs.debug("提交数据出错！" + url + " params: " + $.param(params));
        	}, "json");
		}
		
	},
    
    dataExtends : {needLogin : false},
    data2JsonObj : function(data, contentType){
    	// 为json格式
    	if (contentType == "application/json" || contentType == "text/json") {
    		json = data;
        } else {
        	if (typeof data == 'object') { //js对象
        		json = data;
        	} else { //一般为string
        		try {
        			json = $.parseJSON(data);
        		} catch (e) {
        			json = '';
        		}
        	}
        }
        return json;
    },
    /**    返回值统一方法，判断有无错误（TODO方法名待修改）
     * @param data {Object} 验证对象，可能为json对象也可能为html文本，json对象示例{"success":true,"message":"提示信息"}
     * @param contentType {String} 返回结果类型
     * @param successFn {Function} 成功的执行方法
     * @returns {Boolean} 验证通过时返回true，否则返回false */
    checkError : function(data, contentType, successFn) {
        // 为json格式
    	var json = Touchjs.data2JsonObj(data, contentType);
        if (json) {
            if (json.refresh) { //刷新
                $("[type='submit']").closest("form.searchForm").submit();
            }
            if (json.data && json.data.href && json.data.target && Touchjs.contentMainE) { //含有附加内容,此处是链接
            	Touchjs.contentMainE.find(json.data.target).show().attr("href", json.data.href);
            }
            if (json.message && json.success) {
            	var title = "消息提示";
            	if (json.data && json.data.title) {
            		title = json.data.title;
                }
            	Touchjs.success(title, json.message, successFn);
            }
            if (json.success == false) { //失败
                var logintype = json.data&&json.data.logintype;
                if (logintype) {
                    if (logintype == 'redirect') {
                        window.location.href = json.data.loginurl;
                    } else if(logintype == 'reload') {
                        window.location.reload();
                    }else  {
                    	Touchjs.checkErrorLoginExtend(json, data);
                    }
                } else {
                    if (json.message && !json.success) {
                    	Touchjs.error("错误提示", json.message);
                    }
                }
                return false;
            }
        }
        return true;
    }
    /**    检查返回数据登录的扩展方法（子类可覆盖）
     * @param data {JSON} 返回的对象，一般为json格式
     * @param data {Object} 返回的原始对象，一般为string或者json格式
     * @returns {Boolean} 返回true继续执行后续方法，返回false则不再执行后续方法 */
    ,checkErrorLoginExtend : function(json, data) { //扩展方法
        if (!Touchjs.dataExtends.needLogin) {
        	Touchjs.dataExtends.needLogin = true;
        	Touchjs.openDialog(json.data.loginurl, {}, function(ele, dialog) {
                ele.data("extendRemove", function(index){ //扩展弹出框的remove方法
                	Touchjs.dataExtends.needLogin = false;
                });
                Touchjs.form.initSubmit(ele, function(formE, targetE, data) {//成功后
                    dialog.remove(); //关闭弹出框
                    if (!Touchjs.dialogE) { //非弹出框则只执行刷新
                        var searchForm = $("[type='submit']").closest("form.searchForm");
                        if (searchForm.length > 0) {
                            searchForm.submit();
                        } else {
                            //ShieldJS.activeSiderE.click();
                        }
                    }
                });
            }, "登录", 400, 500, null, "iframe", {"onlyOne":true});
            if (json.message && !json.success) {
            	Touchjs.error(json.message);
            }
        }
        return true;
    }
    ,dynamicBind : function(ele, methodName, namespace, expression, fn) {
    	var containerE = $(document); //直接绑定到document上，否则需要处理，嵌套绑定的重复绑定问题，如果是iframe可能有问题 
    	containerE.off(methodName+namespace, expression).on(methodName+namespace, expression, function() {
    		var $this = $(this);
    		/*var invoker = $this.data("_invoker"+namespace);
			console.log(invoker)
			console.log(ele)
			if (invoker) {
				console.log(invoker.is(ele))
            }
			if (invoker && !invoker.is(ele)) {
				ele.off("click"+namespace, expression); //解绑,否则可能存在冒泡多次绑定的情况
                return;
            }
			$this.data("_invoker"+namespace, ele);*/
    		fn($this);
    	});
    },
	
	/**    窗口resize的处理事件集合（使用时 winResizes["方法名"]=function）
	    @type Key-Value
	 */
	winResizes : {},
	/**    document点击的处理事件集合（使用时 docClicks["方法名"]=function）
	    @type Key-Value
	 */
	docClicks : {}
};
$.fn.paramSelector.defaultOptions = $.extend(true, $.fn.paramSelector.defaultOptions, {
	/**    提示框，可以覆盖，默认采用alert，type字符型（success、error、info、warning）
     * @param title {String} 标题
     * @param message {String} 提示内容
     * @param type {String} 提示类型包括：success、error、info、warning4种  */
    alert : function(title, message, type){ 
    	Touchjs.alert(title, message, type);
    },
    validate : function(formE) { //表单验证方法
    	var options = {};
    	options = getExtendSettings(formE, options); 
        return formE.kvvalid(options);
    },
    mainEle :"body", //关联对象容器
    checkedClass :"checked" //被选中的复选框或单选框的样式
});
//pjax完成后的操作
$(document).on('pjax:success', function(data, status, xhr, options) {
	Touchjs.touch($(data.target));
});
//浏览器resize时调用方法
$(window).resize(function() {
    var resizeMethods = $.extend({},Touchjs.winResizes);
    for(var methodFnName in resizeMethods){
        try {
            if ($.isFunction(resizeMethods[methodFnName])) {
            	resizeMethods[methodFnName]();
            }
        } catch (e) {
            Touchjs.error("resize方法异常："+methodFnName, e);
            return false;
        }
    }
});
//document点击时调用方法，如点击空白关闭弹出层等
$(document).click(function() {
    var clickMethods = $.extend({},Touchjs.docClicks);
    for(var methodFnName in clickMethods){
        try {
            if ($.isFunction(clickMethods[methodFnName])) {
            	clickMethods[methodFnName]();
            }
        } catch (e) {
        	Touchjs.error("点击方法异常："+methodFnName+" "+e);
            return false;
        }
    }
});

// ==================================== 几个插件 ====================================
//自动补全，输入内容提示
;(function($){
	$.fn.autoSuggest = function(options){
		if (options == null) {
			options = {};
        }
        options = $.extend(true, {}, $.fn.autoSuggest.defaultOptions, options);
		var eles = $(this); //表单
		eles.each(function(){
			var $this = $(this);
			var containerE = $("#_searchKeyword_container_div");
			if(containerE.length == 0){
				containerE = $('<div id="_searchKeyword_container_div" style="z-index:99999999;"></div');
				$("body").append(containerE);
				containerE.css("position", "absolute"); //绝对定位
			}
			
			var ajaxpost;
			var index = -1; //下标，用于鼠标移动
			var params = {};
			var keyName = options.key||thisObj.data("key")||thisObj.data("as-key"); //key为自定义
			
			var eventName = options.event;
			if (eventName == "click") { //点击弹出
				$this.click(function(event){
					var thisObj = $(this);
					var url = options.url||thisObj.data("url")||thisObj.data("as-url"); //可能会变
					
					containerE.show().offset({left:thisObj.offset().left + options.offset.left, top:thisObj.offset().top+thisObj.height() + options.offset.top});
					var val = thisObj.val().trim(); //需要现取
    				if(ajaxpost){
    					clearTimeout(ajaxpost); // 先清除
    				}
    				
    				ajaxpost = setTimeout(function(){
						if(val){
							params[keyName] = val;
    						containerE.data("targetE", thisObj).load(url, params).show();	
    						index = -1;
    						return false;
    					}
    				}, 500); //延时0.5
    				
            		return false;
            	});
            } else {  //其他统一处理为键盘按下
            	
            	$this.on("keyup.autoSuggest", function(event){
            		var thisObj = $(this);
            		
            		var key = event.which;
            		if (key == Touchjs.keyCode.ENTER) { // 回车
            			if (containerE.is(":visible") && containerE.find(".selected").length >0) { //如果自动补全可见则选中自动补全
            				containerE.find(".selected").click();
            			} else { //提交
            				var formE = thisObj.closest("form");
            				console.log(1)
            				if(formE.length >0){
            					console.log(2)
            					formE.submit(); //提交表单
            				} else {
            					console.log(3)
            					thisObj.closest(".autoContainer").find(".search").triggerHandler("click");
            				}
            			}
            			return false;
            		} else if(key == Touchjs.keyCode.UP) { // 上
            			var lis = containerE.find("li");
            			index--;
            			if(index == -1){
            				index = lis.length-1;
            			}
            			containerE.find("li").removeClass("selected");
            			containerE.find("li:eq("+index+")").addClass("selected");
            		} else if(key == Touchjs.keyCode.DOWN) { // 下
            			var lis = containerE.find("li");
            			index++;
            			if(index == lis.length){
            				index = 0;
            			}
            			containerE.find("li").removeClass("selected");
            			containerE.find("li:eq("+index+")").addClass("selected");
            		} else {
            			console.log(thisObj.offset().left)
            			console.log(options.offset.left)
            			containerE.show().offset({left:thisObj.offset().left + options.offset.left, top:thisObj.offset().top+thisObj.height() + options.offset.top});
            			if((48<= key && key <= 111) || key == Touchjs.keyCode.BLANK || key == Touchjs.keyCode.BACKSPACE || key == Touchjs.keyCode.DELETE){ // 空格，回退键
            				var val = thisObj.val().trim(); //需要现取
            				if(ajaxpost){
            					clearTimeout(ajaxpost);
            				}
            				var url = options.url||thisObj.data("url")||thisObj.data("as-url"); //可能会变
            				
            				ajaxpost = setTimeout(function(){
            					if(val){
            						params[keyName] = val;
            						containerE.data("targetE", thisObj).load(url, params).show();	
            						index = -1;
            						return false;
            					}
            				}, 500); //延时0.5
            				
            				if(!thisObj.val()){ //值为空则清空并隐藏
            					containerE.html("").hide();
            				}
            			}
            		}
            		
            		
            	}).on("click.autoSuggest", function(){
            		return false;
            	}).on("keydown.autoSuggest", function(event){
            		var key = event.which;
            		if (key == 13){
            			return false;
            		}
            	});
            }
			
			containerE.on("click.autoSuggest", "li", function(){ //选择结果点击
				var jobj = $(this);
				var targetE = containerE.data("targetE").closest("form,.autoContainer");
				var datas = jobj.data(); //用data存储
				for ( var key in datas) {
					targetE.find('[name="'+key+'"]').val(datas[key]);
					targetE.find('[value-to="'+key+'"]').val(datas[key]);
		        }
				containerE.hide();
				return false;
			});
			$(document).on("click.autoSuggest", function(){ //点击空白关闭提示框
				containerE.hide();
			});
		});
	}
	//默认参数
    $.fn.autoSuggest.defaultOptions = {
    	/**	位置偏移 */
		offset : {left:0, top:5},
		/**	提交的字段名称 */
		key : 'k'
    };
})(jQuery);
// 获取修改值后的html
(function ($) {
    var oldHTML = $.fn.html;
    $.fn.formhtml = function () {
        if (arguments.length) return oldHTML.apply(this, arguments);
        $("input,textarea,button", this).each(function () {
            this.setAttribute('value', this.value);
        });
        $(":radio,:checkbox", this).each(function () {
            // im not really even sure you need to do this for "checked"
            // but what the heck, better safe than sorry
            if (this.checked) this.setAttribute('checked', 'checked');
            else this.removeAttribute('checked');
        });
        $("option", this).each(function () {
            // also not sure, but, better safe...
            if (this.selected) this.setAttribute('selected', 'selected');
            else this.removeAttribute('selected');
        });
        return oldHTML.apply(this);
    };
 
    //optional to override real .html() if you want
    // $.fn.html = $.fn.formhtml;
})(jQuery);
